﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
using Microsoft.Xna.Framework;

using NuclexVectorFontContent = Nuclex.Fonts.Content.VectorFontContent;
using NuclexKerningPair = Nuclex.Fonts.Content.VectorFontContent.KerningPair;

namespace Qreed.Xna.Font.ContentPipeline
{
    [ContentTypeWriter]
    public class VectorFontWriter : ContentTypeWriter<VectorFontContent>
    {
        /// <summary>
        /// Compiles a strongly typed object into binary format.
        /// </summary>
        /// <param name="output">The content writer serializing the value.</param>
        /// <param name="value">The value to write.</param>
        protected override void Write(ContentWriter output, VectorFontContent value)
        {
            output.Write(value.FontName);
            output.Write(value.NuclexVectorFontContent.LineHeight);

            foreach (char key in value.CharacterMap.Keys)
            {
                Write(output, value.CharacterMap[key]);
            }

            output.Write('\0');

            WriteKerning(output, value);
        }

        private static void WriteKerning(ContentWriter output, VectorFontContent value)
        {
            output.Write(value.NuclexVectorFontContent.KerningTable.Count);

            foreach (KeyValuePair<NuclexKerningPair, Vector2> kerning in value.NuclexVectorFontContent.KerningTable)
            {
                output.Write(kerning.Key.Left);
                output.Write(kerning.Key.Right);
                output.WriteObject<Vector2>(kerning.Value);
            }
        }

        private void Write(ContentWriter output, VectorFontCharacterContent character)
        {
            output.Write(character.Character);
            output.WriteObject<BoundingBox>(character.BoundingBox);
            output.WriteObject<Vector2>(character.NuclexCharContent.Advancement);
            output.WriteObject<List<Vector2>>(character.NuclexCharContent.Vertices);

            // Dump the outlines
            WriteOutlines(output, character);
            
            // Dump the triangles
            WriteTriangles(output, character);
        }

        private static void WriteTriangles(ContentWriter output, VectorFontCharacterContent character)
        {
            output.Write(character.Triangles.Count);

            foreach (VectorFontCharacterTriangle triangle in character.Triangles)
            {
                for (int i = 0; i < 3; i++)
                    output.Write(triangle.Indices[i]);
            }
        }

        private static void WriteOutlines(ContentWriter output, VectorFontCharacterContent character)
        {
            output.Write(character.Outlines.Count);

            foreach (VectorFontCharacterOutline outline in character.Outlines)
            {
                output.Write(outline.StartIndex);
                output.Write(outline.Length);
                output.Write(outline.IsInnerOutline);
            }
        }

        /// <summary>
        /// Gets the assembly qualified name of the runtime loader for this type.
        /// </summary>
        /// <param name="targetPlatform">Name of the platform.</param>
        /// <returns></returns>
        public override string GetRuntimeReader(Microsoft.Xna.Framework.TargetPlatform targetPlatform)
        {
            return typeof(VectorFontReader).AssemblyQualifiedName;
        }
    }
}
